﻿using System;
using System.Html;
using enyo;
using onyx;

namespace JenkinsView
{
    public class JobDetailListView : enyo.FittableRows, IObserver
    {
        [NoCompile, EvalAtCompile]
        private const string LBL_TITLE = "lblTitle";
        [NoCompile, EvalAtCompile]
        private const string LST_DETAIL = "lstDetail";
        [NoCompile, EvalAtCompile]
        private const string ITM_DETAIL = "itmDetail";
        [NoCompile, EvalAtCompile]
        private const string LBL_NUMBER = "lblNumber";
        //[NoCompile, EvalAtCompile]
        //private const string LBL_URL = "lblUrl";
        [NoCompile, EvalAtCompile]
        private const string LBL_CHANGE = "lblChange";
        [NoCompile, EvalAtCompile]
        private const string LBL_CAUSE = "lblCause";
        [NoCompile, EvalAtCompile]
        private const string TGB_BUILDABLE = "tgbBuildable";
        [NoCompile, EvalAtCompile]
        private const string BTN_BUILD = "btnBuild";
        [NoCompile, EvalAtCompile]
        private const string DLG_BUILD = "dlgBuild";


        protected new string Classes = CssConst.ONYX;

        private new Component[] Components = new Component[]
        {
            new Toolbar() { Kind = onyx.ComponentKind.Toolbar, LayoutKind = enyo.LayoutKind.FittableColumnsLayout, NoStretch = true,
                Components = new Component[]
                {
                    new onyx.IconButton(){ Kind = onyx.ComponentKind.IconButton, Src = ImgSrc.CANCEL, ontap = "navigateBack" },
                    new Control() { Fit = true, Name = LBL_TITLE, Content = "[No Job Selected]", Classes = CssConst.TOOLBAR_TITLE },
                    new onyx.IconButton(){ Kind = onyx.ComponentKind.IconButton, Src = ImgSrc.REFRESH, ontap = "refreshJobDetailList" }
                }
            },

            new List(){ Kind = enyo.ComponentKind.List, Name = LST_DETAIL, Fit = true, Touch = true, OnSetupItem = "setupItem",
                Components = new Component[]
                {
                    new Control(){Name = ITM_DETAIL, Classes = CssConst.PANELS_ITEM,
                        Components = new Component[]
                        {
                            new Control(){Name = LBL_NUMBER, Classes = CssConst.BUILD},
                            new Control(){Name = LBL_CAUSE , Classes = CssConst.START_BY},
                            new Control(){Content = "Change List:<br>", AllowHtml = true, Classes = CssConst.CHANGE_LIST_TITLE},
                            new Control(){Name = LBL_CHANGE, AllowHtml = true, Classes = CssConst.CHANGE_LIST}
                            //new Control(){Name = LBL_URL, Classes = CssConst.URL_VAL}
                        }
                    }
                }                            
            },

            new Toolbar() { Kind = onyx.ComponentKind.Toolbar, LayoutKind = enyo.LayoutKind.FittableColumnsLayout, NoStretch = true,
                Components = new Component[]
                {                    
                    new Control() { Content = "Buildable: " },
                    new onyx.ToggleButton() { Kind = onyx.ComponentKind.ToggleButton, Name = TGB_BUILDABLE, Value = false, OnChange = "buildableChange" },
                    new Control() { Fit = true },
                    new onyx.IconButton(){ Kind = onyx.ComponentKind.IconButton, Name = BTN_BUILD, Src = ImgSrc.BUILD, ontap = "build" }
                }
            },
            
            new LaunchSuccessDialog() { Kind = "JenkinsView.LaunchSuccessDialog", Name = DLG_BUILD, Modal = true, Floating = true, Centered = true, AutoDismiss = false
            }
        };

        public override void Create()
        {
            this.Inherited(Arguments.Value);
            DomainModel.Model.JobDetailManager.SetObserver(this);
        }

        private void NavigateBack()
        {
            DomainModel.Model.NotifyAll(DomainModel.PANEL_NAVIGATE, DomainModel.PREV_VIEW);
        }

        private C FindControl<C>(string name) where C : class
        {
            return this._[name] as C;
        }

        private void SetupItem(Control c, SetupRowEventArgs arg)
        {
            var build = DomainModel.Model.JobDetailManager.ListJobDetails()[arg.Index];

            //Console.Log(build);

            this.FindControl<Control>(LBL_NUMBER).Content = "Build #[" + build.Number + "]: " + build.Result;
            //this.FindControl<Control>(LBL_URL).Content = build.Url;

            CauseData cause = null;
            if (build.Actions != null && build.Actions.Length > 0)
            {
                foreach (var action in build.Actions)
                {
                    if (action.Causes != null && action.Causes.Length > 0)
                    {
                        cause = action.Causes[0];
                        break;
                    }
                }
            }
            if (cause != null)
                this.FindControl<Control>(LBL_CAUSE).Content = cause.ShortDescription + "[" + cause.UserName + "]";

            var lblChange = this.FindControl<Control>(LBL_CHANGE);
            var changes = build.ChangeSet.Items;
            string val = "";
            int limit = 0;
            foreach (var chg in changes)
            {
                val = val + "<hr>" + chg.User + '[' + chg.Date + ']' + chg.Msg;
                limit++;
                if (limit > 5)
                {
                    if (changes.Length > 5)
                        val = val + "<hr>" + "More...";
                    break;
                }
            }
            if (val.Length == 0)
                val = "No change";
            lblChange.Content = val;
        }

        private void RefreshJobDetailList()
        {
            DomainModel.Model.JobDetailManager.ReadJobDetailData(true);
        }

        public void Update(int reason, object arg)
        {
            _fireChange = false;
            JenkinsJobData job;
            ToggleButton tgb = this.FindControl<onyx.ToggleButton>(TGB_BUILDABLE);
            IconButton btn;
            switch (reason)
            {
                case DomainModel.JOB_DETAIL_LIST_CHANGE:
                    job = DomainModel.Model.JobManager.ListCurrentJob();
                    Console.Log("Update ServerListView, reason:" + reason);
                    var lbl = this.FindControl<Control>(LBL_TITLE);
                    lbl.Content = "Job: [" + job.Name + "]";


                    tgb.Value = job.Buildable;//Note:Do not fire onChange


                    btn = this.FindControl<IconButton>(BTN_BUILD);
                    btn.Disabled = !job.Buildable;

                    var lst = this.FindControl<List>(LST_DETAIL);
                    int len = (int)DomainModel.Model.JobDetailManager.ListJobDetails().Length;
                    if (len > 20)
                        len = 20;
                    lst.Count = len;
                    Console.Log("Job Build List Count: " + lst.Count);
                    lst.Refresh();
                    break;

                case DomainModel.JOB_BUILDABLE_CHANGE:
                    job = DomainModel.Model.JobManager.ListCurrentJob();
                    btn = this.FindControl<IconButton>(BTN_BUILD);
                    Console.Log("Change to:" + job.Buildable);
                    btn.Disabled = !job.Buildable;
                    tgb.Value = job.Buildable;
                    break;

                case DomainModel.JOB_BUILD_LAUNCH:
                    var dlg = this._[DLG_BUILD] as onyx.Popup;
                    dlg.Show();
                    break;
            }
            _fireChange = true;
        }

        private bool _fireChange = false;
        private void BuildableChange(Control c, EnyoEventArgs arg)
        {
            if (!_fireChange)
                return;

            var tgb = c as ToggleButton;
            Console.Log("Buildable set to: " + tgb.Value);
            DomainModel.Model.JobDetailManager.ToggleJobBuildableStatus(tgb.Value);
        }

        private void Build(Control c, EnyoEventArgs arg)
        {
            Console.Log("Launch build.");
            DomainModel.Model.JobDetailManager.TriggerBuild();
        }
    }
}
